using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace CoreScene.Scene
{
    public class BillboardNode
    {
        #region Billboard Vertex Element Struct

        private struct BillboardVertex
        {
            private Vector3 mVPos;
            private Vector3 mPPos;
            private Vector4 mCol;
            private Vector2 mTex;
            private Vector2 mSize;
            private float mTwist;

            public void Set(Vector3 vPos, Vector3 pPos, Vector4 col,
                            Vector2 tex,
                            Vector2 size,
                            float twist)
            {
                mVPos = vPos;
                mPPos = pPos;
                mCol = col;
                mTex = tex;
                mSize = size;
                mTwist = twist;
            }

            public static VertexElement[] Elements =
                {
                    new VertexElement(0, 0,  VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0),          //mVPos
                    new VertexElement(0, 12, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Normal, 0),            //mPPos
                    new VertexElement(0, 24, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.Color, 0),             //mCol
                    new VertexElement(0, 40, VertexElementFormat.Vector2, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 0), //mTex
                    new VertexElement(0, 48, VertexElementFormat.Vector2, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 1), //mSize
                    new VertexElement(0, 56, VertexElementFormat.Single,  VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 2), //mTwist
                };

            public const int Size = 12 + 12 + 16 + 8 + 8 + 4;
        }

        #endregion


        /// <summary>
        /// Vertex buffer and declaration
        /// </summary>
        private VertexBuffer mVertexBuffer;
        private VertexDeclaration mVertexDeclaration;

        /// <summary>
        /// Index buffer
        /// </summary>
        private IndexBuffer mIndexBuffer;

        /// <summary>
        /// The effect used to create the billboarding.
        /// </summary>
        private Effect mEffect;

        private readonly String mTextureAsset;
        private Texture2D mTexture;

        // Effect parameters
        private EffectParameter matWorldParam;
        private EffectParameter matViewParam;
        private EffectParameter matProjectionParam;
        private EffectParameter cameraPositionParam;
        private EffectParameter cameraUpParam;
        private EffectParameter textureParam;

        // billboard vertices
        private static Vector3 v0 = -Vector3.UnitX * 0.5f + Vector3.UnitY * 0.5f;
        private static Vector3 v1 = Vector3.UnitX * 0.5f + Vector3.UnitY * 0.5f;
        private static Vector3 v2 = Vector3.UnitX * 0.5f - Vector3.UnitY * 0.5f;
        private static Vector3 v3 = -Vector3.UnitX * 0.5f - Vector3.UnitY * 0.5f;

        private BillboardVertex[] mVertexData = new BillboardVertex[4];
        private int[] mIndexData = new int[4];

        public BillboardNode(Game game, string mTextureAsset)
        {
            this.mTextureAsset = mTextureAsset;
        }

        protected void Render(GameTime gameTime)
        {
/*            // Set common effect parameters ... 
            mEffect.CurrentTechnique = mEffect.Techniques[0];
            matWorldParam.SetValue(Transform);
            matViewParam.SetValue(Scene.ActiveCamera.View);
            matProjectionParam.SetValue(Scene.ActiveCamera.Projection);
            cameraPositionParam.SetValue(Scene.ActiveCamera.Position);
            cameraUpParam.SetValue(Scene.ActiveCamera.UpVector);
            textureParam.SetValue(mTexture);
            mEffect.CommitChanges();*/
        }

        protected void LoadContent()
        {
            /*base.LoadContent();

            // Load the texture
            mTexture = Game.Content.Load<Texture2D>(@"Textures\" + mTextureAsset);

            GraphicsDevice device = GraphicsDevice;

            mVertexBuffer = new DynamicVertexBuffer(device, typeof(BillboardVertex), 4, BufferUsage.WriteOnly);

            // Load and compile the effect
            mEffect = Game.Content.Load<Effect>(@"\Shaders\Billboard");

            // Bind the effect params
            matWorldParam = mEffect.Parameters["matWorld"];
            matViewParam = mEffect.Parameters["matView"];
            matProjectionParam = mEffect.Parameters["matProjection"];
            cameraPositionParam = mEffect.Parameters["cameraPosition"];
            cameraUpParam = mEffect.Parameters["cameraUp"];
            textureParam = mEffect.Parameters["particleTexture"];*/
        }
    }
}